home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------
-
- Reversed API client, ©1995 Dietmar Eilert. Dice:
-
- dcc main.c -// -proto -mi -l reqtoolssr.lib -r -2.0 -o ram:reversed
-
- ------------------------------------------------------------------------------
- */
-
- /// "includes"
-
- #define Prototype extern
-
- #include <exec/exec.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <dos/rdargs.h>
- #include <intuition/intuition.h>
- #include <utility/tagitem.h>
- #include <workbench/startup.h>
- #include <rexx/errors.h>
- #include <rexx/rxslib.h>
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/rexxsyslib_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/reqtools_protos.h>
-
- #include "golded:api/include/golded.h"
-
- Prototype void main(int, char **);
- Prototype int wbmain(struct WBStartup *);
- Prototype void HandleAPI(char *, struct Settings *);
- Prototype ULONG *SendRexxCommand(char *, char *, struct MsgPort *, char *);
- Prototype void Dispatch(struct APIMessage *, struct Settings *);
- Prototype LONG CommandReversedHandler(ULONG *, struct APIMessage *, struct Settings *);
- Prototype void HandleUserInput(struct APIMessage *, struct Settings *);
- Prototype BOOL EvaluateBool(UBYTE *, BOOL);
- Prototype void DoBackspaceReversed(struct APIMessage *, struct EditConfig *);
- Prototype void DoDeleteReversed(struct APIMessage *, struct EditConfig *);
-
- // globals
-
- struct Library *ReqToolsBase;
-
- struct Settings {
-
- BOOL Active;
- };
-
- ///
- /// "main"
-
- int
- wbmain(struct WBStartup *startup)
- {
- if (ReqToolsBase = OpenLibrary("reqtools.library", 37)) {
-
- rtEZRequestTags("No executable - to be used as API client", "OK", NULL, NULL, TAG_DONE);
-
- CloseLibrary(ReqToolsBase);
- }
- }
-
- void
- main(int argc, char **argv)
- {
- static UBYTE version[] = "$VER: Reversed 1.5 (" __COMMODORE_DATE__ ")";
-
- ULONG argArray[] = { 0, 0, 0, 0, 0 };
-
- struct RDArgs *rdArgs;
-
- if (rdArgs = ReadArgs("H=HOST/K/A", argArray, NULL)) {
-
- struct Settings settings = { TRUE };
-
- HandleAPI((UBYTE *)argArray[0], &settings);
-
- FreeArgs(rdArgs);
- }
-
- exit(0);
- }
-
- ///
- /// "api management"
-
- /* --------------------------------- HandleAPI ---------------------------------
-
- Register with GoldED & handle incoming API messages.
-
- */
-
- void
- HandleAPI(host, settings)
-
- char *host;
- struct Settings *settings;
- {
- struct MsgPort *apiPort, *rexxPort;
-
- if (apiPort = CreateMsgPort()) {
-
- if (rexxPort = CreateMsgPort()) {
-
- UBYTE command[255];
- ULONG *result;
-
- sprintf(command, "API PORT=%ld CLASS=%ld", apiPort, API_CLASS_ROOT | API_CLASS_KEY | API_CLASS_REXX);
-
- if (result = SendRexxCommand(host, command, rexxPort, NULL)) {
-
- if (*result == RC_OK) {
-
- BOOL active = TRUE;
-
- do {
-
- struct APIMessage *apiMsg, *nextMsg;
-
- while (!(apiMsg = (struct APIMessage *)GetMsg(apiPort)))
- WaitPort(apiPort);
-
- do {
-
- for (nextMsg = apiMsg; nextMsg; nextMsg = nextMsg->api_Next) {
-
- if (nextMsg->api_State == API_STATE_NOTIFY) {
-
- switch (nextMsg->api_Class) {
-
- case API_CLASS_ROOT:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_DIE:
-
- active = FALSE;
- break;
-
- case API_ACTION_INTRODUCE:
-
- static struct TagItem tags[] = {
-
- API_Client_Name, "Reversed",
- API_Client_Copyright, "Reversed ©1995 Dietmar Eilert",
- API_Client_Purpose, "Right-To-Left input handler",
- API_Client_Template, "REVERSED USE/K,BACK/S,DEL/S",
- API_Client_Template, "NEWLINE",
- TAG_DONE
- };
-
- nextMsg->api_Data = tags;
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
-
- break;
-
- case API_CLASS_KEY:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_VANILLAKEY:
-
- HandleUserInput(nextMsg, settings);
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- break;
-
- case API_CLASS_REXX:
-
- switch (nextMsg->api_Action) {
-
- case API_ACTION_COMMAND:
-
- Dispatch(nextMsg, settings);
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- break;
-
- default:
-
- nextMsg->api_Error = API_ERROR_UNKNOWN;
- }
- }
- }
-
- ReplyMsg((struct Message *)apiMsg);
-
- } while (apiMsg = (struct APIMessage *)GetMsg(apiPort));
-
- } while (active);
- }
- }
-
- DeleteMsgPort(rexxPort);
- }
-
- DeleteMsgPort(apiPort);
- }
- }
-
-
- ///
- /// "command dispatcher"
-
- /* --------------------------------- Dispatch ----------------------------------
-
- Dispatch incoming command: examine command string (command part is uppercase
- already), look for handler function related to command, parse arguments (if
- command supports arguments), call handler.
-
- */
-
- void
- Dispatch(apiMsg, settings)
-
- struct APIMessage *apiMsg;
- struct Settings *settings;
- {
- struct RDArgs *rdArgs, *args;
-
- if (rdArgs = AllocDosObject(DOS_RDARGS, NULL)) {
-
- static char buffer[1024];
-
- // table of supported commands, associated handlers & template strings
-
- static struct parser { char *command; LONG (*handler)(ULONG *, struct APIMessage *, struct Settings *); char *template; } parser[] = {
-
- "REVERSED", (APTR)CommandReversedHandler, "USE/K,BACK/S,DEL/S",
- NULL
- };
-
- ULONG n, argArray[] = { 0, 0, 0, 0, 0, 0 };
-
- struct APIRexxNotify *notify = (struct APIRexxNotify *)apiMsg->api_Data;
-
- // make LF-terminated copy of command string (required by dos/readArgs):
-
- strcpy(buffer, notify->arn_Command);
-
- strcat(buffer, "\12");
-
- for (n = 0; parser[n].command; ++n) {
-
- if (!memcmp(buffer, parser[n].command, strlen(parser[n].command))) {
-
- char *arguments = buffer + strlen(parser[n].command);
-
- rdArgs->RDA_Source.CS_Buffer = arguments;
- rdArgs->RDA_Source.CS_Length = strlen(arguments);
- rdArgs->RDA_Source.CS_CurChr = 0;
- rdArgs->RDA_DAList = NULL;
- rdArgs->RDA_Buffer = NULL;
-
- if (parser[n].template) {
-
- if (args = ReadArgs(parser[n].template, argArray, rdArgs)) {
-
- notify->arn_RC = (*parser[n].handler)(argArray, apiMsg, settings);
-
- FreeArgs(args);
- }
- else {
-
- static UBYTE errorText[81];
-
- notify->arn_RC = RC_WARN;
- notify->arn_CommandError = errorText;
-
- Fault(IoErr(), "IoErr()", errorText, 80);
- }
- }
- else
- notify->arn_RC = (*parser[n].handler)(argArray, apiMsg, settings);
- }
- }
-
- FreeDosObject(DOS_RDARGS, rdArgs);
- }
- }
-
- /* -------------------------- CommandReversedHandler ---------------------------
-
- Handle REVERSED command
-
- template: USE/K,BACK/S,DEL/S
-
- */
-
- LONG
- CommandReversedHandler(argArray, apiMsg, settings)
-
- struct APIMessage *apiMsg;
- struct Settings *settings;
- ULONG *argArray;
- {
- struct EditConfig *config = apiMsg->api_Config;
-
- apiMsg->api_State = API_STATE_CONSUMED;
-
- if (argArray[0]) // USE/K
- settings->Active = EvaluateBool((char *)argArray[0], settings->Active);
-
- if (argArray[1]) // BACK/S
- DoBackspaceReversed(apiMsg, config);
-
- if (argArray[2]) // DEL/S
- DoDeleteReversed(apiMsg, config);
-
- return(RC_OK);
- }
-
- /* ---------------------------- DoBackspaceReversed ----------------------------
-
- Backspace in reversed-input mode
-
- */
-
- void
- DoBackspaceReversed(apiMsg, config)
-
- struct APIMessage *apiMsg;
- struct EditConfig *config;
- {
- static struct APIModifyRequest modifyRequest;
-
- static UBYTE buffer[4096];
-
- UWORD len;
-
- if (len = config->CurrentLen)
- movmem(config->CurrentBuffer, buffer, len);
-
- ++config->Column;
-
- // expand line in case we moved beyond the end of line
-
- while (len <= config->Column)
- buffer[len++] = 32;
-
- if (config->LineNotFixed) {
-
- movmem(buffer, buffer + 1, config->Column);
-
- buffer[0] = 32;
- }
-
- modifyRequest.mr_Next = NULL;
- modifyRequest.mr_Line = config->Line;
- modifyRequest.mr_Column = config->Column;
- modifyRequest.mr_Data = buffer;
- modifyRequest.mr_Size = len;
-
- apiMsg->api_Modify = &modifyRequest;
- }
-
- /* ------------------------------ DoDeleteReversed -----------------------------
-
- Delete in reversed-input mode
-
- */
-
- void
- DoDeleteReversed(apiMsg, config)
-
- struct APIMessage *apiMsg;
- struct EditConfig *config;
- {
- static struct APIModifyRequest modifyRequest;
-
- static UBYTE buffer[4096];
-
- UWORD len;
-
- if (len = config->CurrentLen)
- movmem(config->CurrentBuffer, buffer, len);
-
- if (config->LineNotFixed) {
-
- if (config->Column)
- movmem(config->CurrentBuffer, buffer + 1, config->Column);
-
- *buffer = 32;
- }
-
- modifyRequest.mr_Next = NULL;
- modifyRequest.mr_Line = config->Line;
- modifyRequest.mr_Column = config->Column;
- modifyRequest.mr_Size = len;
- modifyRequest.mr_Data = buffer;
-
- apiMsg->api_Modify = &modifyRequest;
- }
-
- ///
- /// "input handler"
-
- /* ------------------------------ HandleUserInput ------------------------------
-
- Handle user input
-
- */
-
- void
- HandleUserInput(apiMsg, settings)
-
- struct APIMessage *apiMsg;
- struct Settings *settings;
- {
- if (settings->Active) {
-
- struct EditConfig *editConfig = apiMsg->api_Config;
-
- if (editConfig->LineNotFixed) {
-
- static struct APIModifyRequest modifyRequest;
-
- static UBYTE buffer[4096];
-
- UWORD column, len;
-
- editConfig = apiMsg->api_Config;
-
- column = editConfig->Column;
- len = editConfig->CurrentLen;
-
- // get contents of current line
-
- movmem(editConfig->CurrentBuffer, buffer, len);
-
- // shift text to the left (i.e. delete first character)
-
- if (column)
- movmem(buffer + 1, buffer, column);
-
- // insert character
-
- while (len <= column)
- buffer[len++] = 32;
-
- buffer[column] = (UBYTE)apiMsg->api_Data;
-
- // move cursor to the left
-
- if (column)
- --column;
-
- // send modify request to the editor
-
- modifyRequest.mr_Next = NULL;
- modifyRequest.mr_Line = editConfig->Line;
- modifyRequest.mr_Column = column;
- modifyRequest.mr_Size = len;
- modifyRequest.mr_Data = buffer;
-
- apiMsg->api_Modify = &modifyRequest;
- }
-
- // remove input event from input stream
-
- apiMsg->api_State = API_STATE_CONSUMED;
- }
- }
-
- /// "arexx"
- /// "arexx"
-
- /* ---------------------------------- SendRexxCommand -------------------------
-
- Send ARexx message & wait for answer. Return pointer to result or NULL.
-
- */
-
- ULONG *
- SendRexxCommand(port, cmd, replyPort, buffer)
-
- char *cmd, *port, *buffer;
- struct MsgPort *replyPort;
- {
- struct MsgPort *rexxport;
-
- Forbid();
-
- if (rexxport = FindPort(port)) {
-
- struct RexxMsg *rexxMsg, *answer;
-
- if (rexxMsg = CreateRexxMsg(replyPort, NULL, NULL)) {
-
- if (rexxMsg->rm_Args[0] = CreateArgstring(cmd, strlen(cmd))) {
-
- static ULONG result;
-
- rexxMsg->rm_Action = RXCOMM | RXFF_RESULT;
-
- PutMsg(rexxport, &rexxMsg->rm_Node);
-
- do {
-
- WaitPort(replyPort);
-
- if (answer = (struct RexxMsg *)GetMsg(replyPort))
- result = answer->rm_Result1;
-
- } while (!answer);
-
- Permit();
-
- if (answer->rm_Result1 == RC_OK) {
-
- if (answer->rm_Result2) {
-
- if (buffer)
- strcpy(buffer, (char *)answer->rm_Result2);
-
- DeleteArgstring((char *)answer->rm_Result2);
- }
- }
-
- DeleteArgstring((char *)ARG0(answer));
-
- DeleteRexxMsg(answer);
-
- return(&result);
- }
- }
- }
-
- Permit();
-
- return(NULL);
- }
-
- ///
- /// "misc"
-
- /* ---------------------------------- EvaluateBool -----------------------------
-
- Translate boolean string
-
- */
-
- BOOL
- EvaluateBool(arg, value)
-
- UBYTE *arg;
- BOOL value;
- {
- if (arg) {
-
- if (stricmp(arg, "TOGGLE"))
- value = (stricmp(arg, "TRUE") == 0);
- else
- value = !value;
- }
-
- return(value);
- }
-
-
- ///
-